package com.metagurukul.metagranth.service;

import java.util.ArrayList;

import com.metagurukul.metagranth.model.dao.AnswerDAO;
import com.metagurukul.metagranth.model.dao.QuestionDAO;
import com.metagurukul.metagranth.model.dao.TagDAO;
import com.metagurukul.metagranth.model.dao.QuestionTagMappingDAO;
import com.metagurukul.metagranth.model.dao.UserDAO;
import com.metagurukul.metagranth.vo.Answer;
import com.metagurukul.metagranth.vo.AnswerMetaData;
import com.metagurukul.metagranth.vo.MetaData;
import com.metagurukul.metagranth.vo.Question;
import com.metagurukul.metagranth.vo.QuestionTagMapping;
import com.metagurukul.metagranth.vo.Tag;
import com.metagurukul.metagranth.vo.User;

public class Service {

	private final static int NUMBER_OF_QUESTION = 15;

	public static User authentication(User user) throws Exception {
		return UserDAO.authenticate(user);
	}

	public static int saveUserInformation(User user) throws Exception {
		try{
		return UserDAO.save(user);
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static int askQuestion(Question question, Tag tag) throws Exception {
		try{
		int questionId = QuestionDAO.save(question);
		String[] tagNames = tag.getTagName().split(",");
		Tag tempTag = new Tag();
		QuestionTagMapping questionTagMapping = new QuestionTagMapping();
		int status = 0;
		for (int i = 0; i < tagNames.length; i++) {
			tempTag.setTagName(tagNames[i]);
			int tagId = TagDAO.save(tempTag);
			questionTagMapping.setQuestionId(questionId);
			questionTagMapping.setTagId(tagId);
			status = QuestionTagMappingDAO.save(questionTagMapping);
		}
		return status;
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static ArrayList<Tag> getTagsList() throws Exception {
		try{
		return TagDAO.getTagsList();
	}catch(Exception exception) {
		throw exception;
	}
	}

	/**
	 * this function will call dao class to find latest 'number' of questions
	 * where 'number' is a constant which tells no of questions to retrieve. if
	 * any exception occurs that is throws which is handeled by action class.
	 * 
	 * 
	 * public static ArrayList getLatestQuestions() { final int number = 15;
	 * 
	 * ArrayList<Question> list = null; list =
	 * QuestionDAO.searchLatestQuestion(number); return list; }
	 * @throws Exception 
	 **/
	public static ArrayList<MetaData> getLatestQuestions() throws Exception {
		try{
		ArrayList<Question> questionList = QuestionDAO.searchLatestQuestion(NUMBER_OF_QUESTION);
		return getMetaDataOfQuestions(questionList);
		}catch(Exception exception) {
			throw exception;
		}
	}

	private static ArrayList<MetaData> getMetaDataOfQuestions(ArrayList<Question> questionList) throws Exception {
		try{
		ArrayList<MetaData> metadataList = new ArrayList<MetaData>();
		for (Question question : questionList) {
			
			metadataList.add(getMetaDataOfQuestion(question));
		}
		return metadataList;
	}catch(Exception exception) {
		throw exception;
	}
	}

	private static MetaData getMetaDataOfQuestion(Question question) throws Exception {

		try{
		MetaData metadata = new MetaData();
		metadata.setQuestion(question);
		int questionId = question.getQuesId();
		metadata.setTagList(TagDAO.getTagsByQuestionId(questionId));
		int userId = question.getQuesId();
		metadata.setUser(UserDAO.getUserById(userId));
		ArrayList<Answer> answerList = AnswerDAO.getAnswerByQuestionId(questionId);
		ArrayList<AnswerMetaData> answerMetaDataList = new ArrayList<AnswerMetaData>();
		for (Answer answer : answerList) {

			AnswerMetaData answerMetaData = getMetaDataOfAnswer(answer);
			answerMetaDataList.add(answerMetaData);
		}
		metadata.setAnswerMetaDataList(answerMetaDataList);
		return metadata;
	}catch(Exception exception) {
		throw exception;
	}
	}

	private static AnswerMetaData getMetaDataOfAnswer(Answer answer) throws Exception {
		try{
		AnswerMetaData answerMetaData = new AnswerMetaData();
		answerMetaData.setAnswer(answer);
		int userId = answer.getUid();
		answerMetaData.setUser(UserDAO.getUserById(userId));

		return answerMetaData;
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static ArrayList<Question> getAllQuestions() throws Exception {
		try{
		return QuestionDAO.getAllQuestions();
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static ArrayList<Question> searchByQuestion(String byQuestion) throws Exception {

		try{
		return QuestionDAO.searchByQuestion(byQuestion);
	}catch(Exception exception) {
		throw exception;
	}
	}

	/**
	 * This function will check weather the username entered by the user during
	 * signUp already exists with the same name in database or not
	 * @throws Exception 
	 */

	public static int ifUserExists(User user) throws Exception {

		try{
		int status = -1;
		User isUsernameExists = UserDAO.userSet(user);
		if (isUsernameExists == null) { // no such user name exists! UserName is
										// available

			status = 1;
		} else {
			status = 0; // Username is not available
		}
		return status;
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static ArrayList<Question> searchByTag(String query) throws Exception {
		
		try{
		ArrayList<Question> questionList = new ArrayList<Question>();
		String tagNames[] = query.split(",");

		for (String tagName : tagNames) {
			System.out.println(tagName);
			Tag tagObject = new Tag();
			tagObject.setTagName(tagName.trim());
			QuestionDAO questionDaoObject = new QuestionDAO();
			ArrayList<Tag> tagList = TagDAO.searchByTag(tagObject);
			for (Tag tag : tagList) {
				questionList.addAll(questionDaoObject.searchByTag(tag));
			}
		}
		return questionList;

	}catch(Exception exception) {
		throw exception;
	}
	}

	public static ArrayList<Question> searchByQuestionAndTag(String byQuestion,	String byTag) throws Exception {
	try{
		ArrayList<Question> questionList = searchByTag(byTag);
		questionList.addAll(searchByQuestion(byQuestion));
		return questionList;
	}catch(Exception exception) {
		throw exception;
	}
	}

	public static MetaData getQuestionDetailByQuestionId(int questionId) throws Exception {
		
		try{
		Question question=QuestionDAO.searchQuestionbyId(questionId);
		MetaData metaData=getMetaDataOfQuestion(question);
		return metaData;
	}catch(Exception exception) {
		throw exception;
	}
	}

}
